package com.atguigu.chapter16

import scala.collection.immutable
import scala.math._

/**
 *
 * @description: 作业讲解
 * @time: 2020-06-01 10:22
 * @author: baojinlong 
 **/
object Exercise01 {
  def myName(x: (String, Int)): Int = {
    x._2
  }


  def myName3(x: (String, Int)): Int = {
    x._2
  }

  def main(args: Array[String]): Unit = {
    println(swap[Int, Int](20, 10))
    println(swap(Array("10", "20", 33)).toBuffer)
    println(sum(List(Some(1), Some(2), None, Some(3), None, Some(330))))
    val h1 = mergeFunction(f1, f2)
    println(h1(2).get)
    println(h1(1) + " " + h1(0))
    println(values(x => x * x, -5, 5))
    println(values(inputFun, -5, 5).reverse)
    val inputArr = Array(1, 22, 344, 12, 3455, 666)
    println(inputArr.reduceLeft(getMax))
    println(factorial(3))
    println(largest(x => 10 * x - x * x, 1 to 10))
    println(largest((x: Int) => 10 * x - x * x, 1 to 10))
    myUnless(condition = 1 > 8) {
      println("wo草")
    }
    myUnless {
      1 > 8
    } {
      println("wo草")
    }
    myUnless(condition = false) {
      println("我进来了")
    }
    println("###############")
    val lines = List("atguigu hello scala aaa bbb ccc aaa bbb ccc uuu", "atguigu hello scala aaa bbb ccc aaa bbb ffff gggg")
    // 1.首先将集合中每一个单集合数据进行分隔
    val wordList: List[String] = lines.flatMap(_.split(" "))
    println("wordList= " + wordList)
    // 2.做成对偶List才能分组统计
    val wordTuple: List[(String, Int)] = wordList.map((singleWord: String) => (singleWord, 1))
    println("wordTuple= " + wordTuple)
    // 3.分组将相同的单词放入到同一个组中
    val stringToTuples: Map[String, List[(String, Int)]] = wordTuple.groupBy((wordTuple: (String, Int)) => wordTuple._1)
    println("stringToTuples= " + stringToTuples)
    // 4.对各个元组进行统计,可以使用stringToTuples.map(x=>x)可以查看x的类型
    val stringToInt: Map[String, Int] = stringToTuples.map((x: (String, List[(String, Int)])) => (x._1, x._2.size))
    println("stringToInt= " + stringToInt)
    // 5.排序
    stringToInt.toList.sortBy((x: (String, Int)) => x._2)
    val tuples: List[(String, Int)] = stringToInt.toList.sortBy(myName).reverse
    val tuples2: List[(String, Int)] = stringToInt.toList.sortBy(x => myName3(x))
    val tuples3: List[(String, Int)] = stringToInt.toList.sortBy(_._2).reverse
    println("result= " + tuples3)
    println("合并写法 fmgmtsr")
    val stringToInt1: Map[String, Int] = lines.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).map(x => (x._1, x._2.size))
    println("map=" + stringToInt1)
    println("toList= " + stringToInt1.toList)
    println("result= " + lines.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).map(x => (x._1, x._2.size)).toList.sortBy(_._2).reverse)
  }

  /**
   * 交换两个数据
   *
   * @param inputParam
   * @tparam T
   * @tparam S
   * @return
   */
  def swap[T, S](inputParam: (T, S)): Any = {
    inputParam match {
      case (a, b) => (b, a)
      case _ => print("没有匹配到")
    }
  }

  /**
   * 交换数组中前两个数据
   *
   * @param inputArr
   * @return
   */
  def swap(inputArr: Array[Any]): Array[Any] = {
    inputArr match {
      case Array(first, second, rest@_*) => Array(second, first) ++ rest
      case _ => inputArr
    }
  }

  // 返回非None的和
  def sum(inputList: List[Option[Int]]): Int = {
    inputList.map((x: Option[Int]) => x.getOrElse(0)).sum
  }


  // 返回非None的和
  def sumSimple(inputList: List[Option[Int]]): Int = {
    // 只出现过一次直接移除x
    inputList.map(_.getOrElse(0)).sum
  }

  def f1(x: Double): Option[Double] = {
    if (x > 0) {
      Some(sqrt(x))
    } else {
      None
    }
  }

  def f2(x: Double): Option[Double] = {
    if (x != 1) {
      Some(1 / (x - 1))
    } else {
      None
    }
  }

  // 将上述两个函数合并成一个函数[入参是double,返回结果是Option[Double]
  def mergeFunction(f1: Double => Option[Double], f2: Double => Option[Double]): Double => Option[Double] = {
    // 返回一个匿名函数
    x: Double => {
      if (f1(x).isEmpty || f2(x).isEmpty) {
        None
      } else {
        f2(x)
      }
    }
  }

  def values(fun: Int => Int, low: Int, height: Int): immutable.Seq[(Int, Int)] = {
    // 定义一个空集合存放对偶元素,方法参数是函数的要么直接传入函数名,要么用大括号写函数
    var newList = List[(Int, Int)]()
    (low to height).foreach {
      x => {
        newList = (x, fun(x)) :: newList
      }
    }
    newList
  }

  def inputFun(value: Int): Int = {
    value * value
  }

  /**
   * 求出两个数的最大值
   *
   * @param num1
   * @param num2
   * @return
   */
  def getMax(num1: Int, num2: Int): Int = {
    if (num1 > num2) {
      num1
    } else {
      num2
    }
  }

  /**
   * 求阶乘
   *
   * @param n
   * @return
   */
  def factorial(n: Int): Int = {
    1 to n reduceLeft ((x: Int, y: Int) => x * y)
    // 1 to n reduceLeft ((x, y) => x * y)
    // 1 to n reduceLeft (_ * _)
  }

  /**
   * 将集合中每一个元素经过函数处理后返回处理后的最大值
   *
   * @param fun
   * @param inputs
   * @return
   */
  def largest(fun: Int => Int, inputs: Seq[Int]): Int = {
    // 将输入的元素中每一个值经过函数fun处理后返回
    // inputs.map((n: Int) => fun(n))
    // inputs.map(n => fun(n))
    inputs.map(fun(_)).max
  }

  // 实现一个unless抽象控制,工作机制类似if,但是条件是反过来的
  def myUnless(condition: => Boolean)(codeBlock: => Unit): Unit = {
    if (!condition) {
      codeBlock
    }
  }
}
